'''
# 项目：简易通讯录管理系统
# 版本：ver-2
# 更新日期：2024/1/5
# 作者：刘攀
# 感谢帮助名单：葛羽嘉（python语法课程教学及技术指导），周乐言（提供一小部分思路）
'''

import tkinter as tk
import tkinter.simpledialog as simdia
import tkinter.messagebox as mesbox
import csv
import os
import re

############################## 一些文本信息和定义 #################################
mian_info = ("注意：本程序版权属于刘攀©所有，未经刘攀©书面授权，任何企业、网站、"
             "个人不得转载、摘编、镜像或利用其它方式使用本程序内容。")
opt_info = ("具体使用规则如下：\n1、<添加>按钮可为通讯录一次性新增“姓名”、“电话”和“邮箱”三条"
            "同属于一人的相关信息\n2、<删除>按钮可为通讯录一次性删除“姓名”、“电话”和“邮箱”三条"
            "同属于一人的相关信息\n3、<查找>按钮可以根据“姓名”、“电话”和“邮箱”三条信息中的任意"
            "一条信息，找出相关人的其他信息\n4、<显示>按钮可以显示当前通讯录中的所有内容")
userInfLib = {'123': '123', '456': '456'}
show_info = False


################################## 函数定义 ##################################
# 载入数据
def load_contacts(csv_file_path):
    if not os.path.exists(csv_file_path):
        return []
    with open(csv_file_path, mode='r', newline='', encoding='utf-8') as file:
        reader = csv.DictReader(file)
        return list(reader)


def save_contacts(contacts, csv_file_path):
    with open(csv_file_path, mode='w', newline='', encoding='utf-8') as file:
        fields = ['Name', 'Phone', 'Email']
        writer = csv.DictWriter(file, fieldnames=fields)
        writer.writeheader()
        for contact in contacts:
            writer.writerow(contact)

csv_file_path = 'contacts.csv'
contacts = load_contacts(csv_file_path)

# 已注册的用户信息显示
def show_user():
    display_text1 = "用户1：\n账号：123    密码：123\n用户2：\n账号：456    密码：456"
    mesbox.showinfo("用户详情", display_text1)

# 无法注册信息显示
def show_not_register():
    display_text2 = "对不起，暂不开放注册"
    mesbox.showinfo("注册详情", display_text2)

# 退出登陆主窗口
def quit_cmd1():
    rootWin.destroy()

# 登陆账号密码检测，判断是否为已经注册的用户
def entry_cmd1():
    global show_info
    if var1.get() in userInfLib:
        if var2.get() == userInfLib[var1.get()]:
            show_inf_y()
            show_info = True
            crea_win1()

            rootWin.withdraw()
        else:
            show_inf_n()
            show_info = False
    else:
        show_inf_n()
        show_info = False

# 退出登陆的确认
def ask_y_n():
    global ans
    ans = mesbox.askyesno(title='是否退出程序', message='确认退出')
    if ans:
        quit_cmd1()

# 显示登陆成功信息
def show_inf_y():
    mesbox.showinfo(message='欢迎使用本系统', title='身份确认')

# 显示登陆失败信息
def show_inf_n():
    mesbox.showinfo(message='账号或密码错误', title='账号管理')

def show_inf_01():
    mesbox.showinfo("查找结果", "未找到匹配的联系人.")

def show_inf_02(s=''):
    mesbox.showinfo("查找结果", s)



# 查找内容输入框
def find_ask_str(n=0):
    if n==0:
        pass
    # 从人名找
    elif n==1:
        ask_name = simdia.askstring(title='查找', prompt='输入名字：', initialvalue='例：liupan')
        if ask_name:
            result_text = ""
            for contact in contacts:
                if ask_name.lower() in contact['Name'].lower():
                    result_text += f"姓名: {contact['Name']}, 电话: {contact['Phone']}, Email: {contact['Email']}\n"
            if result_text:
                show_inf_02(result_text)
                # mesbox.showinfo("查找结果", result_text)
            else:
                show_inf_01()
                # mesbox.showinfo("查找结果", "未找到匹配的联系人.")
    # 从号码找
    elif n==2:
        ask_num = simdia.askinteger(title='查找', prompt='输入号码：', initialvalue=110110110)
        if str(ask_num).isdigit():
            result_text = ""
            for contact in contacts:
                if str(ask_num) in contact['Phone']:
                    result_text += f"姓名: {contact['Name']}, 电话: {contact['Phone']}, Email: {contact['Email']}\n"
            if result_text:
                show_inf_02(result_text)
                # mesbox.showinfo("查找结果", result_text)
            else:
                show_inf_01()
                # mesbox.showinfo("查找结果", "未找到匹配的联系人.")
    # 从邮箱找
    elif n==3:
        ask_email = simdia.askstring(title='查找', prompt='输入邮箱：', initialvalue='例：liupan@15.org')
        if ask_email:
            result_text = ""
            for contact in contacts:
                if ask_email in contact['Email']:
                    result_text += f"姓名: {contact['Name']}, 电话: {contact['Phone']}, Email: {contact['Email']}\n"
            if result_text:
                show_inf_02(result_text)
                # mesbox.showinfo("查找结果", result_text)
            else:
                show_inf_01()
                # mesbox.showinfo("查找结果", "未找到匹配的联系人.")
    else:
        pass

# 字符串形式显示通讯录内容
def display_contacts():
    display_text = ""
    for contact in contacts:
        display_text += f"姓名: {contact['Name']}, 电话: {contact['Phone']}, Email: {contact['Email']}\n"
    # global var4
    # var4 = display_text
    mesbox.showinfo("通讯录", display_text)

#创建操作窗口
def crea_win1():

    # 显示内容
    def update_window():
        display_contacts()
        win1_lab1.update()

    # 退出操作窗口
    def quit_cmd2():
        win1.destroy()
        rootWin.deiconify()

    # 添加操作的窗口
    def add_contact_window():
        def submit_contact():
            name = name_entry.get()
            phone_number = phone_entry.get()
            email = email_entry.get()

            # 判断添加的电话以及邮箱是否合法
            num_pattern = r"1[3456789]\d{9}"
            email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
            num_judge = re.match(num_pattern, phone_number)
            email_judge = re.search(email_pattern, email)
            if num_judge:
                if email_judge:
                    contacts.append({'Name': name, 'Phone': phone_number, 'Email': email})
                    save_contacts(contacts, csv_file_path)
                    mesbox.showinfo("成功", "已增加新的联系人.")
                    add_window.destroy()
                else:
                    mesbox.showerror("失败", "<邮箱>格式错误.")
            # 电话和邮箱格式同时错误
            elif not email_judge:
                mesbox.showerror("失败", "<电话号码>和<邮箱>格式错误.")
            else:
                mesbox.showerror("失败", "<电话号码>格式错误.")

        add_window = tk.Toplevel(win1)
        add_window.title("添加一个联系人")
        # 设置弹出窗口的尺寸
        add_window.geometry("300x200+300+300")
        add_window.resizable(width=False, height=False)
        add_window.attributes("-topmost", 1)

        tk.Label(add_window, text="姓名:").pack()
        name_entry = tk.Entry(add_window)
        name_entry.pack()

        tk.Label(add_window, text="电话:").pack()
        phone_entry = tk.Entry(add_window)
        phone_entry.pack()

        tk.Label(add_window, text="Email:").pack()
        email_entry = tk.Entry(add_window)
        email_entry.pack()

        submit_button = tk.Button(add_window, text="提交", command=submit_contact, width=6, height=1)
        submit_button.place(x=125, y=160)

    # 删除操作的窗口
    def del_contact_window():
        def submit_contact():
            name = name_entry.get()
            phone = phone_entry.get()
            email = email_entry.get()
            contacts.remove({'Name': name, 'Phone': phone, 'Email': email})
            save_contacts(contacts, csv_file_path)
            mesbox.showinfo("成功", "已删除新的联系人.")
            del_window.destroy()

        ################################ 创建删除窗口 ########################################
        del_window = tk.Toplevel(win1)
        del_window.title("删除一个联系人")
        # 设置弹出窗口的尺寸
        del_window.geometry("300x200+300+300")
        del_window.resizable(width=False, height=False)
        del_window.attributes("-topmost", 1)

        tk.Label(del_window, text="姓名:").pack()
        name_entry = tk.Entry(del_window)
        name_entry.pack()

        tk.Label(del_window, text="电话:").pack()
        phone_entry = tk.Entry(del_window)
        phone_entry.pack()

        tk.Label(del_window, text="Email:").pack()
        email_entry = tk.Entry(del_window)
        email_entry.pack()

        submit_button = tk.Button(del_window, text="提交", command=submit_contact, width=6, height=1)
        show_button = tk.Button(del_window, text="显示", command=display_contacts, width=6, height=1)

        submit_button.place(x=85, y=160)
        show_button.place(x=165, y=160)

    # 查找操作的窗口
    def find_win():

        # 退出查找操作的窗口
        def quit_cmd3():
            win2.destroy()

        # 按名字查找
        def find_from_name():
            find_ask_str(1)

        # 按号码查找
        def find_from_num():
            find_ask_str(2)

        # 按邮箱查找
        def find_from_email():
            find_ask_str(3)

        ################################ 查找功能窗口 ###################################
        win2 = tk.Toplevel(win1)
        win2.title("查找")
        win2.geometry('100x155+900+300')
        # 无边框
        win2.overrideredirect(True)
        win2.attributes("-topmost", 1)

        win2_lf1 = tk.LabelFrame(win2, text="查找选项")

        win2_btn1 = tk.Button(win2_lf1, text='用名字找', command=find_from_name, width=10, height=1)
        win2_btn2 = tk.Button(win2_lf1, text='用电话找', command=find_from_num, width=10, height=1)
        win2_btn3 = tk.Button(win2_lf1, text='用邮箱找', command=find_from_email, width=10, height=1)
        win2_btn4 = tk.Button(win2, text='关闭查找', command=quit_cmd3, width=10, height=1)

        win2_lf1.pack(fill="both", expand=1)

        win2_btn1.pack()
        win2_btn2.pack()
        win2_btn3.pack()
        win2_btn4.pack()


    ##################################### 功能管理窗口 #################################################
    # 创建管理窗口
    win1 = tk.Toplevel()
    win1.title('通讯录管理')
    win1.geometry('500x400+400+300')
    win1.resizable(width=False, height=False)
    # 无边框
    win1.overrideredirect(True)

    # 创建控件
    win1_lf1 = tk.LabelFrame(win1, text="通讯录系统使用详情")

    win1_btn1 = tk.Button(win1, text='退出', command=quit_cmd2, width=6, height=1)
    win1_btn2 = tk.Button(win1, text='添加', command=add_contact_window, width=6, height=1)
    win1_btn3 = tk.Button(win1, text='删除', command=del_contact_window, width=6, height=1)
    win1_btn4 = tk.Button(win1, text='查找', command=find_win, width=6, height=1)
    win1_btn5 = tk.Button(win1, text='显示', command=update_window, width=6, height=1)

    win1_lab1 = tk.Label(win1_lf1, text=opt_info, width=200, height=10)
    win1_mes1 = tk.Message(win1_lf1,text=opt_info, width=400)

    win1_mes1.config(font=10)

    win1_btn1.place(x=440, y=360)
    win1_btn2.place(x=10, y=360)
    win1_btn3.place(x=80, y=360)
    win1_btn4.place(x=150, y=360)
    win1_btn5.place(x=220, y=360)

    win1_mes1.pack()
    win1_lf1.pack(fill="both", expand=1)

########################################### 登陆窗口 ###################################################

# 创建窗口
rootWin = tk.Tk()
rootWin.title("开始界面")
# 界面尺寸
rootWin.geometry('400x300+400+300')
rootWin.resizable(width=False, height=False)

# 创建控件
var1 = tk.StringVar()
var2 = tk.StringVar()
var3 = tk.StringVar()
var4 = tk.StringVar()

var3 = '测试有没有显示文字'

lab1 = tk.Label(rootWin, text='通讯录管理系统', width=14, height=1)
# 账号标签
lab2 = tk.Label(rootWin, text='账号:', width=6, height=1)
# 密码标签
lab3 = tk.Label(rootWin, text='密码:', width=6, height=1)

mess1 = tk.Message(rootWin,text=mian_info,width=320, )  #
# 创建账号输入框
en1 = tk.Entry(rootWin, textvariable=var1)
# 创建密码输入框，密码用*显示
en2 = tk.Entry(rootWin, show='*', textvariable=var2)


btn1 = tk.Button(rootWin, text='退出', command=ask_y_n, width=6, height=1)
btn2 = tk.Button(rootWin, text='登陆', command=entry_cmd1, width=6, height=1)
btn3 = tk.Button(rootWin, text='用户', command=show_user, width=6, height=1)
btn4 = tk.Button(rootWin, text='注册', command=show_not_register, width=6, height=1)

lab1.config(bg='gainsboro')
mess1.config(bg='gainsboro')

# 大标题
lab1.place(x=160, y=5)
lab2.place(x=100, y=50)
lab3.place(x=100, y=80)

mess1.place(x=37,y=180)

en1.place(x=150, y=50)
en2.place(x=150, y=80)

btn1.place(x=340, y=260)
btn2.place(x=150, y=120)
btn3.place(x=10, y=260)
btn4.place(x=220, y=120)

rootWin.mainloop()
